//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.IO.Packaging;
using OpenLS.Core.Serialization;
using OpenLS.Spreadsheet.Serialization;
using OpenLS.Vml;

namespace OpenLS.Spreadsheet
{
    class Dialogsheet: Sheet
    {
        public Dialogsheet(Workbook workbook, SheetInfo info): base (workbook, info)
        {

        }

        internal override IEnumerable<CustomSheetView> GetCustomSheetViews()
        {
            return this.CustomSheetViews;
        }

        internal override string UriPrefix
        {
            get { return "/xl/dialogsheets/sheet"; }
        }

        internal override string ContentType
        {
            get { return SpreadsheetConstants.DialogsheetContentType; }
        }
        internal override string RelationshipType
        {
            get { return SpreadsheetConstants.DialogsheetRelationshipType; }
        }


        internal override void ReadXmlCore(ReadContext context)
        {
            using (ReadContext c = context.Read("dialogsheet"))
            {
                Properties = c.ReadOptionalElement<SheetProperties>("sheetPr");
                if (c.ReaderLocalName == "sheetViews")
                {
                    using (ReadContext c2 = c.Read("sheetViews"))
                    {

                        while (c2.ReaderLocalName == "sheetView")
                        {
                            SheetViews.Add(c2.ReadElement<SheetView>(delegate { return new SheetView(this); }));
                        }
                    }
                }
                FormatProperties= c.ReadOptionalElement<SheetFormatProperties>("sheetFormatPr");
                SheetProtection = c.ReadOptionalElement<SheetProtection>("sheetProtection");
                _customSheetViews = c.ReadOptionalListElement<CustomSheetView>("customSheetViews", "customSheetView");
                PrintOptions = c.ReadOptionalElement<PrintOptions>("printOptions");
                PageMargins = c.ReadOptionalElement<PageMargins>("pageMargins");
                PageSetup = c.ReadOptionalElement<PageSetup>("pageSetup");
                HeaderFooter = c.ReadOptionalElement<HeaderFooter>("headerFooter");
                if (c.ReaderLocalName == "drawing")
                {
                    using (ReadContext c2 = c.Read("drawing"))
                    {
                        PackageRelationship rel = c2.Part.GetRelationship(c2.GetString(OfficeConstants.RelationshipNamespace + "id"));
                        PackagePart drawingPart = c2.Part.Package.GetPart(PackUriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri));
                        using (Stream stream = drawingPart.GetStream())
                        {
                            DrawingData = new byte[stream.Length];
                            stream.Read(DrawingData, 0, DrawingData.Length);
                        }
                    }
                }
                LegacyDrawing = OpenLS.Spreadsheet.LegacyDrawingHelper.ReadOptionalVmlElementAs(c, "legacyDrawing");
                _LegacyDrawingHF = Spreadsheet.LegacyDrawingHelper.ReadOptionalVmlElementAs(c, "legacyDrawingHF");
                _oleObjects.Clear();
                _oleObjects.AddRange(c.ReadElements<OleObject>("oleObjects", "oleObject"));
                Extension = c.ReadOptionalElement<ExtensionElement>("extLst");
            }
        }

        internal override void WriteXmlCore(WriteContext context)
        {
            using (WriteContext c = context.Write("dialogsheet"))
            {
                c.WriteOptionalElement(Properties);
                if (SheetViews.Count > 0)
                {
                    using (WriteContext c2 = c.Write("sheetViews"))
                    {
                        foreach (SheetView v in SheetViews)
                            c2.WriteElement(v);
                    }
                }
                c.WriteOptionalElement(FormatProperties);
                c.WriteOptionalElement(SheetProtection);
                if (CustomSheetViews.Count > 0)
                {
                    using (WriteContext c2 = c.Write("customSheetViews"))
                    {
                        foreach (CustomSheetView v in CustomSheetViews)
                            c2.WriteElement(v);
                    }
                }
                c.WriteOptionalElement(PrintOptions);
                c.WriteOptionalElement(PageMargins);
                c.WriteOptionalElement(PageSetup);
                c.WriteOptionalElement(HeaderFooter);
                if (DrawingData != null)
                {
                    using (WriteContext c2 = c.Write("drawing"))
                    {
                        PackageRelationship rel = c2.Part.CreateRelationship(c2.GetAvailableUri("vmlDrawing{0}.vml"), TargetMode.Internal, SpreadsheetConstants.VmlDrawingRelationshipType);
                        Uri ucp = PackUriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);
                        PackagePart newPart = c2.Part.Package.CreatePart(ucp, SpreadsheetConstants.VmlContentType, CompressionOption.Maximum);
                        using (Stream stream = newPart.GetStream())
                        {
                            stream.Write(DrawingData, 0, DrawingData.Length);
                        }
                        c2.SetString(OfficeConstants.RelationshipNamespace + "id", rel.Id);
                    }
                }
                Spreadsheet.LegacyDrawingHelper.WriteOptionalVmlElementAs(_legacyDrawing, c, "legacyDrawing");
                Spreadsheet.LegacyDrawingHelper.WriteOptionalVmlElementAs(_LegacyDrawingHF, c, "legacyDrawingHF");
                c.WriteElements(_oleObjects);
                c.WriteOptionalElement(Extension);
            }
        }
        private SheetProperties _sheetPr;

        public SheetProperties Properties
        {
            get { return _sheetPr; }
            set { _sheetPr = value; }
        }
        private readonly List<SheetView> _sheetViews = new List<SheetView>();

        public List<SheetView> SheetViews
        {
            get { return _sheetViews; }
        }
        private SheetFormatProperties _sheetFormatPr;

        public SheetFormatProperties FormatProperties
        {
            get { return _sheetFormatPr; }
            set { _sheetFormatPr = value; }
        }
        private SheetProtection _sheetProtection;

        public SheetProtection SheetProtection
        {
            get { return _sheetProtection; }
            set { _sheetProtection = value; }
        }
        private List<CustomSheetView> _customSheetViews = new List<CustomSheetView>();

        public List<CustomSheetView> CustomSheetViews
        {
            get { return _customSheetViews; }
        }
        private PrintOptions _printOptions;

        public PrintOptions PrintOptions
        {
            get { return _printOptions; }
            set { _printOptions = value; }
        }
        private PageMargins _pageMargins;

        public PageMargins PageMargins
        {
            get { return _pageMargins; }
            set { _pageMargins = value; }
        }
        private PageSetup _pageSetup;

        public PageSetup PageSetup
        {
            get { return _pageSetup; }
            set { _pageSetup = value; }
        }
        private HeaderFooter _headerFooter;

        public HeaderFooter HeaderFooter
        {
            get { return _headerFooter; }
            set { _headerFooter = value; }
        }
        private byte [] _drawingData;

        public byte[] DrawingData
        {
            get { return _drawingData; }
            set { _drawingData = value; }
        }
        private VmlDrawing _legacyDrawing;

        public Vml.VmlDrawing LegacyDrawing
        {
            get { return _legacyDrawing; }
            set { _legacyDrawing = value; }
        }
        private ExtensionElement _extLst;
        private List<OleObject> _oleObjects = new List<OleObject>();
        private Vml.VmlDrawing _LegacyDrawingHF;
        internal PropertyChangedEventHandler DimensionPropertyChanged;

        public ExtensionElement Extension
        {
            get { return _extLst; }
            set { _extLst = value; }
        }


        internal void NotifyDimensionPropertyChanged (Dimension dim, string propertyName)
        {
            var e = DimensionPropertyChanged;
            if (e != null)
                e(dim, new PropertyChangedEventArgs(propertyName));
        }
    }
}
